package com.hu.user.controller;


import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hu.common.common.HttpStatus;
import com.hu.common.controller.BaseController;
import com.hu.common.pojo.User;
import com.hu.common.pojo.dto.QueryInfo;
import com.hu.common.pojo.dto.Response;
import com.hu.common.pojo.dto.TableDataInfo;
import com.hu.common.pojo.dto.UserDTO;
import com.hu.user.service.IUserService;
import com.hu.user.utils.TokenUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ServerWebExchange;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author hu
 * @since 2023-07-27
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    @Resource
    private IUserService userService;

    /**
     * 使用mybatis的方式实现查询
     * 由于该类继承了BaseController，所以可以直接调用BaseController中的success方法
     * 先调用BaseController的success方法，BaseController又去调了Response中的构造器
     * 最终的结果就是我们封装的response类
     * @return
     */
    @GetMapping("/getAll")
    public Response getAll() {
        // 其实就等同于： Response.success(List)
        return success(userService.getAllUserList());
    }

    @PostMapping("/pagemybatis")
    public TableDataInfo findPage2(@RequestBody QueryInfo<User> queryInfo) {
        startPage(queryInfo);
        return getDataTable(userService.queryProperty(queryInfo.getQueryObject(), queryInfo.getOrderStatus(), queryInfo.getColumnName()));
    }

    // 新增或者更新
    @PostMapping("/save")
    public Response save(@RequestBody User user) {
        return success(userService.saveOrUpdate(user));
    }

    @DeleteMapping("/{id}")
    public Response delete(@PathVariable Integer id) {
        return success(userService.removeById(id));
    }

    @PostMapping("/del/batch")
    public Response deleteBatch(@RequestBody List<Integer> ids) {
        return success(userService.removeByIds(ids));
    }

    @GetMapping
    public Response findAll() {
        return success(userService.list());
    }

    @GetMapping("/{id}")
    public Response findOne(@PathVariable Integer id) {
        return success(userService.getById(id));
    }

    @GetMapping("/page")
    public Response findPage(@RequestParam Integer pageNum,
                               @RequestParam Integer pageSize,
                               @RequestParam(defaultValue = "") String username,
                               @RequestParam(defaultValue = "") String nickname,
                               @RequestParam(defaultValue = "") String email) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(username)){
            queryWrapper.like("username",username);
        }
        if (!"".equals(nickname)){
            queryWrapper.like("nickname",nickname);
        }
        if (!"".equals(email)){
            queryWrapper.like("email",email);
        }
        return success(userService.page(new Page<>(pageNum, pageSize), queryWrapper));
    }

    @PostMapping("/login")
    @ResponseBody
    public Response login(@RequestBody UserDTO userDTO) {
            String username = userDTO.getUsername();
            String password = userDTO.getPassword();
            // 校验字符是否为空,为空则没必要再去数据库中查询
            if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
                return error(HttpStatus.BAD_REQUEST,"参数错误");
            }
        UserDTO dto = userService.login(userDTO);

        // 获取当前登录的用户信息
        // User currentUser = TokenUtils.getCurrentUser();
        // System.out.println("当前登录的用户信息-->"+currentUser.getNickname());

        return success("登录成功",dto);
    }

    @PostMapping("/register")
    public Response register(@RequestBody UserDTO userDTO) {
        String username = userDTO.getUsername();
        String password = userDTO.getPassword();
        // 校验字符是否为空,为空则没必要再去数据库中查询
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return error(HttpStatus.BAD_REQUEST,"参数错误");
        }
        // 从数据库查看当前用户名是否已经存在
        Boolean register = userService.isRegister(userDTO.getUsername());
        if (register) {
            return error(HttpStatus.BAD_REQUEST,"该用户名已被占用，换一个试试吧~~");
        }else {
            User user = userService.register(userDTO);
            // 把user返回给前端
            return success("注册成功",user);
        }
    }

    // 用户信息导出
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
        // 从数据库查询所有数据
        List<User> list = userService.list();
        // 通过工具类创建writer，写到磁盘路径
        // ExcelWriter bigWriter = ExcelUtil.getBigWriter(filesUploadPath + "/用户信息.xls");
        // 在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 自定义标题
        writer.addHeaderAlias("username","用户名");
        writer.addHeaderAlias("password","密码");
        writer.addHeaderAlias("nickname","昵称");
        writer.addHeaderAlias("email","邮箱");
        writer.addHeaderAlias("phone","电话");
        writer.addHeaderAlias("address","地址");
        writer.addHeaderAlias("create_time","创建时间");
        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("用户信息","utf-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }

    // 用户信息导入
    @PostMapping("/imp")
    public Response imp(MultipartFile file) throws Exception {
        System.out.println("file"+file);
        // 从前端传来的file中获取inputStream
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        reader.addHeaderAlias("用户名","username");
        reader.addHeaderAlias("密码","password");
        reader.addHeaderAlias("昵称","nickname");
        reader.addHeaderAlias("邮箱","email");
        reader.addHeaderAlias("电话","phone");
        reader.addHeaderAlias("地址","address");
        reader.addHeaderAlias("座右铭","motto");
        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        List<User> list = reader.readAll(User.class);
        userService.saveBatch(list);
        return success(true);
    }

    // 根据username查询用户详细信息
    @GetMapping("/username/{username}")
    public Response findUserInfo(@PathVariable String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        return success(userService.getOne(queryWrapper));
    }

    // 根据token查询用户详细信息
    @GetMapping("/token/{token}")
    public User findUserByToken(@PathVariable String token) {
        User currentUser = TokenUtils.getCurrentUser(token);
        return currentUser;
    }

    @GetMapping("/count")
    public Response getCount() {
        long count = userService.count();
        return success(count);
    }
}
